home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-06 / qb_ipx.zip / IPX.DOC < prev    next >
Text File  |  1992-08-03  |  20KB  |  395 lines

  1. Hello.
  2.  
  3. I  have been working on a NetWare space-war game (for up to six players)  for
  4. the  past few months, and one of the programming requirements was to be  able
  5. to  send and receive IPX packets. Since the project is in QuickBASIC  4.0,  I
  6. had to write my own IPX routines (I have routines in Pascal and "C").
  7.  
  8. I  am  releasing my IPX routines into the public domain so that you need  not
  9. have  to write your own. I am taking a lot of time here doing this to meet  a
  10. need. If I put forth effort now, it may save dozens of folks time by them not
  11. having to figure it out themselves.
  12.  
  13. This  document is intended to highlight some of the information you will need
  14. to know about IPX. It is NOT intended to replace better information.
  15.  
  16. To begin. . . . .
  17.  
  18. There  should have been seven files in the ZIP/PAK/LZH/ZOO/ARJ/ARC  file  you
  19. downloaded. The file files should be:
  20.  
  21.           IPX.BAS             All routines in one file
  22.           IPXS.BAS            Sample IPX Send Code
  23.           IPXS.EXE            Sample Executable IPX Send
  24.           IPXR.BAS            Sample IPX Receive Code
  25.           IPXR.EXE            Sample Executable IPX Receive
  26.           CHAT.BAS            A Chat program using these routines
  27.           IPX.DOC             This Document
  28.  
  29. If  you  do  not have all of these files, and would like a copy of them  all,
  30. call  me, David Rice, at 714-458-6000. You may also leave a message  at  Fido
  31. Node 102/902 (The Skeptic Tank).
  32.  
  33. These  two  routines  are NOT included with the QuickBASIC  NetWare  Function
  34. Library I wrote previously. That library may be found on various BBSs by  the
  35. name  QBNW-20.ZIP,  which  includes  Print  Queues,  connection  information,
  36. network address retrieval, etc. If you downloaded this file thinking you were
  37. getting QBNW-20, well, this ain't it.
  38.  
  39. Note  that  the routines here are IPX and =not= SPX. I chose to use  IPX  for
  40. several  reasons. The first is, it's faster than SPX. Another is, IPX packets
  41. have  a  slightly larger datagram area, and can thus carry more  information.
  42. The  third is, IPX is a "connectionless" packet protocol whereas SPX requires
  43. a  connection  before a packet may be sent and received. With IPX,  the  user
  44. need not be logged onto the network: she or he need only load IPX.COM.
  45.  
  46. IPX does NOT guarantee delivery, as SPX does. When an IPX packet is received,
  47. its  header will contain the address of the computer that sent it. This means
  48. that  even though IPX does not guarantee delivery, the program you  write  to
  49. send and receive the packets can do the checking itself. For example:
  50.  
  51.        Computers A and B are running your program.
  52.  
  53.        Computer  A  sends a packet to Computer B and then  checks  the
  54.        packet's  INUSE  flag.  When  that  flag  turns  to  zero  (0),
  55.        Computer A goes into listen mode. If the INUSE flag stays  non-
  56.        zero  for  five or ten seconds (you decide), there  may  be  an
  57.        error,  and  your  program may handle that  error  as  you  the
  58.        programmer sees fit.
  59.  
  60.        So  now  Computer  B finishes whatever it was doing,  and  goes
  61.        into  listen  mode. It says, "Hey! I have a  packet  here."  It
  62.        reads  the packet, setting the INUSE flag to zero (see  how  it
  63.        works?).  It  should  then  go into  Send  mode,  and  send  an
  64.        acknowledgment to Computer A, saying "Got it, thanks a  bunch!"
  65.        It  will know which computer to send it to, because the  packet
  66.        it received has the address in the header.
  67.  
  68. Though I suspect you may send multiple IPX packets without checking to see if
  69. the  first arrived before sending the second, there is a good reason to  wait
  70. for  the  confirmation. IPX packets are not sequenced, as SPX ones  are.  The
  71. computer doing the "Listening" may very well receive the second packet before
  72. it  receives the first! We wouldn't want the space ship to blow up before the
  73. torpedo hits it, now would we?! Of course not!
  74.  
  75. I  suggest you use the first four bytes of the Datagram (the area that  holds
  76. the packets' data) as a sequence field. Every time a computer sends a packet,
  77. add 1 to this counter. This way, the receiving computer will know that it has
  78. missed a packet when it reads the Datagram's sequence value and notices  that
  79. it incremented by 2 (or more) instead of 1.
  80.  
  81. If  you  do use a Sequence field, the size of your Datagram will go from  546
  82. bytes to 542 bytes.
  83.  
  84. IPX  packets may be fragmented. This means that if you have data that  is  in
  85. logical  chunks, you may specify those chunks within the ECB structure.  Your
  86. size limit is still 546 bytes. Why do multible fragments? Suppose you wish to
  87. send  in one packet several different variables, such as A$, B$, C$, and  D$.
  88. You could define five fragments: one for the 30-byte header, and four for the
  89. four variables. Behold:
  90.  
  91.           TYPE ECBStructure
  92.              LinkAddressOff   AS Integer
  93.                   .
  94.                   .
  95.                   .
  96.              FragAddOfs1   AS INTEGER
  97.              FragAddSeg1   As INTEGER
  98.              FragSize1   AS INTEGER
  99.              FragAddOfs2   AS INTEGER
  100.              FragAddSeg2   AS INTEGER
  101.              FragSize2   AS INTEGER
  102.                   .
  103.                   .
  104.              FragAddOfs5   AS INTEGER
  105.              FragAddSeg5   AS INTEGER
  106.              FragSize5   AS INTEGER
  107.           END TYPE
  108.           '
  109.           DIM ECBS AS ECBStructure
  110. '         '
  111.           ECBS.FragAddOfs1 = VARPTR(IPXS)
  112.           ECBS.FragAddSeg1 = VARGEG(IPXS)
  113.           ECBS.FragSize1 = 30
  114.           ECBS.FragAddOfs2 = VARPTR(A$)
  115.           ECBS.FragAddSeg2 = VARSEG(A$)
  116.           ECBS.FragSize2 = LEN(A$)
  117.                   .
  118.                   .
  119.           ECBS.FragAddOfs5 = VARPTR(D$)
  120.           ECBS.FragAddSeg5 = VARSEG(D$)
  121.           ECBS.FragSize5 = LEN(D$)
  122.  
  123. In  the send sample IPXS, the Destination Network was set to four zeros.  See
  124. the  code,  IPXS.DestNode. This means that the IPX packet will be distributed
  125. on the default network: the one that the computer is hard cabled to--- if you
  126. are  sending packets across bridges or otherwise to another network, YOU MUST
  127. KNOW THAT NETWORK'S ADDRESS AND PUT IT IN THIS FIELD.
  128.  
  129. In  the send sample, IPXS, the Destination  Node Address was set to six  FFs.
  130. This  means the packet will be "broadcast" to all computers. If you  wish  to
  131. send  a packet to a specific computer, you must place that computer's address
  132. in IPXR.DestNode.
  133.  
  134. Enhanced Program Flow:
  135.  
  136.      Computer A sends a broadcast packet to DestNode FFFFFFFFFFFF,  saying
  137.      "Anyone out there?"
  138.  
  139.       Computer  B receives the broadcast packet and sends an acknowledgment
  140.       to Computer A. "Yep, I'm here. What of it?"
  141.  
  142.       Computer  A receives the acknowledgment packet, and MAKES A  NOTE  OF
  143.       ITS  ADDRESS.  From  then  on, it sends only  specifically  addressed
  144.       packets.
  145.  
  146.       Along   comes   Computer   C.  It  sends  a  broadcast   packet   (on
  147.       FFFFFFFFFFFF) Saying "Anyone out there?"
  148.  
  149.        Both  Computer  A  and  Computer B send  acknowledgment  packets  to
  150.        Computer C.
  151.  
  152.        Both Computer A and Computer B make a note of Computer C's address.
  153.  
  154.        Computer C makes a note of Computer A's and Computer B's address.
  155.  
  156.        Now all computers know each others' address, and none need broadcast
  157.        on  FFFFFFFFFFFF. If a fourth computer, Computer D, comes along,  it
  158.        makes a broadcast on FFFFFFFFFFFF, and all computers make a note  of
  159.        the new computer's address, and the new computer makes a note of the
  160.        other computers' address.
  161.  
  162. It's not difficult to keep track of all this. Just REDIM an array to hold all
  163. of  the Network Addresses (IPXS.DestNet) and another to hold the Network Node
  164. Addresses  (IPXS.DestNode), and keep track of how many computers are  running
  165. your computer. This is called a Distribution List.
  166.  
  167. If  you're  a bright lass or lad, you will have noticed something wrong  with
  168. sending  packets  out as broadcasts (FFFFFFFFFFFF). If  a  computer  sends  a
  169. packet on a socket, it may very well be the only one to receive it! In  other
  170. words, it can, and will, be talking to itself. The solution, of course, is to
  171. use  two sockets: one to send, one to listen. However, that makes yet another
  172. problem! Consider:
  173.  
  174.       Your program sends on Socket 1, and listens on Socket 2. THAT'S the
  175.       problem! Any other computer running your program will be doing  the
  176.       same  damn thing; listening on a socket that none send on  but  all
  177.       listen to, and sending on a socket all send on but none listen  to.
  178.       That's no way to strike up a meaningful conversation.
  179.  
  180.       If  you  try and be smart, and say "I'll listen and send on  both,"
  181.       you'll  just end up talking to yourself again, and that's where  we
  182.       came into this house of mirrors!
  183.  
  184.       The solution? If you must broadcast, check ALL received packets for
  185.       the source node, and if it came from one's own computer, ignore it!
  186.       That is, even though you're talking to yourself, you don't have  to
  187.       listen, let alone talk back.
  188.  
  189. Suppose  a  computer runs your program, and it is the only one at the  moment
  190. running  it. This computer must wait for other computers to run your program.
  191. You  could  have  the computer send and receive on the same  socket:  send  a
  192. packet then listen for a packet. When the computer receives a packet that  is
  193. not  self-addressed  (Node  number), that means a new  computer  has  started
  194. running your program.
  195.  
  196. For  the same scenario above, but using two sockets (which is a better idea),
  197. your  computer  could  send on one socket and listen on  another.  After  the
  198. computer  listens for 3 or 5 seconds, have your program SWITCH  SOCKETS,  but
  199. AFTER  your program issues an IXPCancelS call on the original SEND.  See  the
  200. CHAT.BAS program.
  201.  
  202. If  one  computer wants to quit the program (for instance, his or  her  space
  203. ship  gets blasted to hell-an-gone), it is deemed proper etiquette  for  that
  204. computer  to  send a packet to all of the other computers, so that  they  may
  205. remove that computer from their distribution list.
  206.  
  207. However,  you may wish to have one of the computers running your  program  to
  208. act  as  a  "server." That is, the first computer to run your  program  would
  209. respond to new computer's broadcasts by sending the new computer ALL  OF  THE
  210. OTHER COMPUTERS' ADDRESSES. All other computers would ignore broadcasts. This
  211. is  how  my  space wars game tells a new computer which other  computers  are
  212. playing  the  game. When that player exits the game, the  job  of  server  is
  213. passed on to another computer still playing the game.
  214.  
  215. (The   above  description  does  not  describe  a  SAP  (Service  Advertising
  216. Protocol). SAPs are different animals completely. A SAP is much like  an  IPX
  217. packet,  but  it  is  sent every 60 seconds, and it adds its  name  to  every
  218. Bindery on every file server on the network, even over bridges and routers.)
  219.  
  220. Your  program  should also keep track of unsent packets. If a packet  is  not
  221. sent  within  30  seconds  (give or take), you may assume  that  there  is  a
  222. problem: the destination computer may have exited the program. When a  packet
  223. has  not been delivered, your program should automatically remove it from the
  224. distribution list--- assume the user quit the program.
  225.  
  226. You  may also want to have a "user time-out." If the program detects that the
  227. user  has done nothing for ten minutes, have her or his computer send a  "I'm
  228. Quitting  This Program" message to all of the other users, so that  they  may
  229. remove  that  computer from their distribution list. Then  have  her  or  his
  230. program quit.
  231.  
  232. In  the  sample  programs, the Datagram size was set to 546  bytes.  You  may
  233. actually  send from 0 to 546 bytes. I just set it to 546 bytes in the  sample
  234. as the default.
  235.  
  236. Why  would  someone send a zero-byte Datagram? Suppose in  the  program  flow
  237. above,  Computer  A sends a broadcast on FFFFFFFFFFFF. All this  computer  is
  238. interested  in  is telling the other computers currently using  your  program
  239. that  it  is running your program: the IPX header holds Computer A's address,
  240. and  Computer  A has no need to send any data in the Datagram. Likewise,  the
  241. acknowledgment packets need not send any data in the Datagram,  because  they
  242. are  only telling Computer A their addresses, which is contained in their IPX
  243. packet headers.
  244.  
  245. If  the packet does not send any data, set the variable ECBS.FragSize  to  30
  246. (which is the size of the header). Likewise, if the size of the data you wish
  247. to send is, for instance, 30 bytes, set ECBS.FragSize to 60 (30 bytes for the
  248. header, and 30 bytes for the Datagram). There is no reason to send a 546 byte
  249. packet when you do not need to.
  250.  
  251. Packet type is important. There are eight type ranges defined:
  252.  
  253.           0         Unknown Type
  254.           1         Routing Information Packet
  255.           2         Echo Packet
  256.           3         Error Packet
  257.           4         Packet Exchange Packet (PXP or PEP)
  258.           5         Sequenced Packet Protocol Packet (SPX)
  259.           16-31     Experimental
  260.           17        NetWare Core Protocol
  261.  
  262. For IPX, you must use type 0 or 4.
  263.  
  264. The  sockets you use is also very important. You cannot use just any sockets,
  265. because  there very well may be programs your networks are using that already
  266. use  that socket for their processes. There are several known sockets you  do
  267. NOT want to use. These are (in HEX):
  268.  
  269.           1         Routing information
  270.           2         Echo
  271.           3         Error
  272.           20-3F     Experimental
  273.           1-0BB8    Xerox's usage
  274.           0BB9--    Dynamically assignable
  275.           0451      Novell File Server
  276.           0452      Novell Service Advertising Packet
  277.           0453      Novell Routing
  278.           0455      Novell NetBIOS
  279.           0456      Novell Diagnostic
  280.  
  281. If  you call Novell, they will assign you socket numbers, above &H8000.  Tell
  282. them  how  many  you  need,  and your program's name.  You  do  not  want  to
  283. inadvertently  step on someone else's sockets. You may wish to  ask  for  one
  284. more than you think you'll need, to be on the safe side.
  285.  
  286. However, there's a much better way to choose a socket. Let IPX do it for you!
  287. If  you  set your socket to zero, IPX will assign a random socket  number  to
  288. your program.
  289.  
  290. You  may also arbitrarily assign a socket number from within the "dynamically
  291. assignable" range, such as I did in IPXS and IPXR (&H5555). This is  a  range
  292. from &H4000 to &H7FFF.
  293.  
  294. It  is  a good idea to set up SEVERAL ECBs, one for each process your program
  295. will  perform.  That  is,  one  for  Sending,  one  for  Listening,  one  for
  296. Broadcasts, one for each specific process your program will do.
  297.  
  298. You  may  build  a packet and send it at a predetermined time  by  using  the
  299. IPXSchedule  call.  You  pass  to this routine  the  number  of  clock  ticks
  300. (approximately  1/18  of a second each tick) to delay. When  the  delay  time
  301. counts  down to zero, the packet is sent, no matter what your program happens
  302. to  be  doing at the time. This can be handy for performing repetitive packet
  303. sends.
  304.  
  305. You  may  cancel  an event, whether it be a Scheduled, Send,  or  Listen,  by
  306. calling  IPXCancel. If the event has already occurred, you  can't  cancel  it
  307. (obviously).
  308.  
  309. Want to know how long an IPX event took? Call IPXMarker before and then after
  310. performing a send or listen, then subtract the first result from the  second.
  311. The time will be in 1/18 of seconds, from 0 to 65,535.
  312.  
  313. You  may use the call GETMYADDRESS to get the computer's network address.  It
  314. will return the Network and Node address, in Binary and Hex.
  315.  
  316. It is considered proper to send IPX Disconnects to computers you are finished
  317. talking to. This will tell the other computer's network driver to abandon all
  318. services  it  was performing FOR YOU; it will continue to perform  all  other
  319. services.
  320.  
  321. When  you set an address variable, the routines expect it to be a String,  in
  322. Binary.  For  instance, if the address is A0000F18, use the  FUNCTION  called
  323. HexToBinary$("A0000F18") to convert from Hex to String Binary. To go  in  the
  324. opposite direction, i.e. to convert a String of Binary, use TurnToHex.
  325.  
  326. The  first  step  in sending or receiving an IPX packet is  to  determine  if
  327. IPX.COM  has  been loaded. If IPX.COM is not loaded, and you try  to  send  a
  328. packet,  the computer will probably lock up. EMM386.EXE will give you  a  GPE
  329. (General Protection Error). If this happens, you must reboot the machine.
  330.  
  331. Use  the FUNCTION IPXInstalled% to see if IPX.COM is installed. It returns  a
  332. zero if it is =NOT= installed.
  333.  
  334. Your computer may open many sockets at once. You could have your program send
  335. packets  on  one socket, and receive packets on another socket. If  you  call
  336. OPENSOCKET and receive a Status other than 0 or FF, do not attempt to send  a
  337. packet on that socket--- see the Novell documentation on SHELL.CFG on how  to
  338. increase the default socket count.
  339.  
  340. After the socket is opened, you may send packets.
  341.  
  342. After    each   SENDPACKET   call,   your   program   "should"   also    call
  343. RELENQUISHCONTROL. This allows your computer to give up some CPU time to  the
  344. IPX  handler. This is NOT required, however (unless your computer program  is
  345. acting as a server, or multi-tasking). It is just good packet etiquette.
  346.  
  347. When  you  are finished with a socket, please close it with CLOSESOCKET.  The
  348. routines will close a socket for you when the program terminates, but  it  is
  349. still good practice to close it specifically in the program.
  350.  
  351. Please note that in the IPXS (send) sample, the packet is sent only once, and
  352. then  a  loop to check the InUseFlag is entered. Do =NOT= place the  call  to
  353. SENDPACKET within the loop.
  354.  
  355. Also note in the IPXR (receive) sample, the call to SOCKETLISTEN is =NOT=  in
  356. a loop.
  357.  
  358. Once  your computer program issues a Send or Listen, IPX.COM will handle  the
  359. packet.  IPX.COM  will  modify the state of the  ECB  (Event  Control  Block)
  360. depending  on the status of the packet. All you need do is monitor  the  ECB,
  361. while IPX.COM does its best to deliver the packet, or receive the packet.
  362.  
  363. If  you  plan on writing a multi-user game, you may wish to look  into  SAPs,
  364. where  one computer playing the game acts as the game's server, and  all  the
  365. other  computers  send  information to this server.  The  server  would  then
  366. distribute  this information to all computers playing the game: this  way,  a
  367. host  game-playing computer need only send and receive IPX packets  from  one
  368. computer (the server), while the server sends to all computers in the game.
  369.  
  370. Take  the  SAP approach for your game one step further. Suppose your  program
  371. periodically checks each player's computer to determine the fastest  computer
  372. playing. Your program could assign that computer as the server. Then  when  a
  373. faster  computer starts to play your game, the server could  switch.  If  the
  374. server quits, the next fastest computer could act as the server.
  375.  
  376. Use  the IPXMarker routine to determine which computer is the fastest in  IPX
  377. event handling: the 80486 50Mhz machine might be the fastest machine, but  if
  378. it  is on another network, over a bridge, gateway, or router, it may well  be
  379. the slowest in delivering packets!
  380.  
  381. There is much more to IPX and SPX use. However, I only went through the  very
  382. basics in this document.
  383.  
  384. Finally,  any  information in this document could be completely wrong;  also,
  385. the  programs I wrote could also be wrong. I take no responsibility,  and  no
  386. blame,  if  you find that these routines fail to work, wreak havoc with  your
  387. network  or love life, or get you fired from your job because your boss  says
  388. "That idiot programmer crashed the system again!" one too many times.
  389.  
  390. Good Luck!
  391.  
  392. David Rice
  393. July 24, 1992
  394.  
  395.